package com.example.acontainerd.controller;

import com.example.acontainerd.entity.RoleEntity;
import com.example.acontainerd.properties.AContainerdProperties;
import com.example.acontainerd.repos.RoleRepo;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.env.Environment;
import org.springframework.core.env.PropertySource;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.context.support.StandardServletEnvironment;

import java.util.HashMap;
import java.util.Map;

import lombok.extern.slf4j.Slf4j;

@RequestMapping("/api")
@RestController
@Slf4j
public class HelloController {

    @Autowired
    private Environment environment;

    @Autowired
    private RoleRepo roleRepo;

    @Autowired
    private StringRedisTemplate redisTemplate;

    @Autowired
    private AContainerdProperties properties;

    @Autowired
    private RestTemplate restTemplate;

    @Value("${spring.application.name}")
    private String myName;

    @GetMapping("/hello")
    public String hello() {
        log.info("Hello endpoint accessed");
        return "Hello from a-containerd Spring Boot Application!";
    }

    @GetMapping("/health")
    public String health() {
        log.info("Health check endpoint accessed");
        return "Application is running successfully!";
    }

    @PostMapping("/config")
    public String getConfigValue(@RequestBody ConfigRequest request) {
        log.info("Config endpoint accessed with request: {}", request);
        if (request == null || request.getKey() == null) {
            log.warn("Config request is null or key is missing");
            return "Configuration key is required";
        }
        String value = environment.getProperty(request.getKey());
        if (value != null) {
            log.info("Config key '{}' found with value: {}", request.getKey(), value);
            return "Key: " + request.getKey() + ", Value: " + value;
        } else {
            log.warn("Config key '{}' not found", request.getKey());
            return "Configuration key '" + request.getKey() + "' not found";
        }
    }

    @PostMapping("/redis/set")
    public Map<String, Object> setRedis(@RequestBody Map<String, String> body) {
        String key = body.get("key");
        String value = body.get("value");
        redisTemplate.opsForValue().set(key, value);
        log.info("Redis set: {} -> {}", key, value);
        Map<String, Object> resp = new HashMap<>();
        resp.put("result", "ok");
        return resp;
    }

    @GetMapping("/redis/get")
    public Map<String, Object> getRedis(@RequestParam String key) {
        String value = redisTemplate.opsForValue().get(key);
        log.info("Redis get: {} -> {}", key, value);
        Map<String, Object> resp = new HashMap<>();
        resp.put("key", key);
        resp.put("value", value);
        return resp;
    }

    // 请求体类
    public static class ConfigRequest {
        private String key;

        public String getKey() {
            return key;
        }

        public void setKey(String key) {
            this.key = key;
        }
    }

    @GetMapping("/db/{id}")
    public RoleEntity getRole(@PathVariable("id") Long id) {
        log.info("Database role lookup requested for id: {}", id);
        RoleEntity role = roleRepo.findById(id).orElse(null);
        if (role != null) {
            log.info("Role found for id {}: {}", id, role);
        } else {
            log.warn("Role not found for id: {}", id);
        }
        return role;
    }

    @GetMapping("/getPropertySources")
    public String getPropertySources() {
        return ((StandardServletEnvironment) environment)
                .getPropertySources()
                .stream()
                .map(PropertySource::getName)
                .toList()
                .toString();
    }

    @GetMapping("/a-key")
    public String getAKey() {
        return this.properties.getAKey();
    }

    @GetMapping("/hello/{source}")
    public String hello(@PathVariable String source) {
        String str = this.hi(source);
        String url = "http://another-containerd-app-service/api/hi/" + str;
        return restTemplate.getForObject(url, String.class);
    }

    @GetMapping("/hi/{source}")
    public String hi(@PathVariable String source) {
        return source + "~" + this.myName;
    }
}